package org.subside.model.aop;

import org.aspectj.lang.ProceedingJoinPoint;

/**
 * @Author : zhangbo
 * @data : 2024/5/15
 * @description : Aspectj实现切面
 */
public class Logger {
    /**
     * 实现步骤：
     * 1.添加依赖，aop与aspectj表达式的依赖
     * 2.创建spring的主配置文件，bean内的命名空间要添加aop的
     * 3.创建业务代码并编写日志记录代码(事务管理代码)
     * 4.将业务层与日志记录层注入spring容器
     * 5.<aop:config>--aop配置\
     *         aop:aspect--aop切面
     *                aop:before--通知内容与通知类型
     */
//      <!--注入业务层-->
//    <bean id="serviceImp" class="com.apesource.service.AccountServiceImp"></bean>
//    <!--注入日志层-->
//    <bean id="logger" class="com.apesource.util.Logger"></bean>
//
//    <!--配置AOP-->
//    <aop:config>
//        <aop:aspect id="aopAspect" ref="logger">
//            <!--切点-->
//        <aop:pointcut id="dian" expression="execution(* com.apesource.service.*.*(..))" />
//       <!--前置通知-->
//            <aop:before method="beforeMethod" pointcut-ref="dian"></aop:before>
//            <!--返回通知-->
//            <aop:after-returning method="returnMethod" pointcut-ref="dian"></aop:after-returning>
//            <!--异常通知-->
//            <aop:after-throwing method="throwingMethod" pointcut-ref="dian"></aop:after-throwing>
//            <!--后置通知-->
//            <aop:after method="afterMethod" pointcut-ref="dian"></aop:after>
//        <aop:around method="arroundMethod" pointcut-ref="dian"></aop:around>
//        </aop:aspect>
//    </aop:config>
    /**
     * 切点表达式配置语法
     * execution(修饰符 返回值 包名称.类名称.方法名称(参数列表))
     * eg:
     *     execution(public void com.apesource.service.ServiceImp.findAll())
     * 1.修饰符可以省略代表任意
     *     execution(返回值 包名称.类名称.方法名称(参数列表))
     * 2.返回值可以使用“*”代表任意
     *     execution(* 包名称.类名称.方法名称(参数列表))
     * 3.包名可以使用“*”代表任意名称
     *     execution(* *.*.*.类名称.方法名称(参数列表))
     * 4.包名可以使用“..”代表任意个数
     *     execution(* *...类名称.方法名称(参数列表))
     * 5.类名与方法名可以使用“*”代表任意
     *     execution(* *...*.*(参数列表))
     * 6.参数列表可以使用".."代表任意个数任意类型
     *     execution(* *...*.*(..))
     */
    public void beforeMethod(){
        System.out.println("前置通知");
    }
    public void returnMethod(){
        System.out.println("返回通知");
    }
    public void throwingMethod(){
        System.out.println("异常通知");
    }
    public void afterMethod(){
        System.out.println("后置通知");
    }

    public Object arroundMethod(ProceedingJoinPoint pjp){

        Object obj =null;

        try {
            System.out.println("前置通知");
            //主业务代码
            Object[] args =pjp.getArgs();
            obj =pjp.proceed(args);
//            int a = 10/0;
            System.out.println("返回通知");
        } catch (Throwable throwable) {
            throwable.printStackTrace();
            System.out.println("异常通知");
        } finally {
            System.out.println("后置通知");
        }
        return obj;
    }
}
